Skip to content

Method: berechneAnwesenheitsZeitraeume(LocalDate, ChronoUnit)

1: package zeit;
2:
3: import util.CollectionHelper;
4: import zeit.eintraege.KalenderEintrag;
5: import zeit.eintraege.KalenderEintragGenerell;
6: import zeit.eintraege.KalenderEintragTyp;
7: import zeit.eintraege.KalenderEintragVisitor;
8: import zeit.eintraege.MaschinenBelegungEintrag;
9: import zeit.eintraege.MenschBelegungEintrag;
10: import zeit.eintraege.Zeitraum;
11:
12: import java.time.LocalDate;
13: import java.time.LocalDateTime;
14: import java.time.temporal.ChronoUnit;
15: import java.util.Collection;
16: import java.util.HashSet;
17: import java.util.Optional;
18: import java.util.Set;
19: import java.util.stream.Collectors;
20:
21: /**
22: * Ein Kalender für Mitarbeiter.
23: * Mitarbeiter sind immer standardmäßig von Beginn_Kernarbeitszeit bis Ende_Kernarbeitszeit anwesend und können Kalendereinträge vom Typ
24: * {@link KalenderEintragTyp Anwesend}, {@link KalenderEintragTyp Abwesend},
25: * {@link KalenderEintragTyp Belegt} und {@link KalenderEintragTyp Krank} enthalten.
26: * Darüberhinaus kann dieser Kalender keine {@link MaschinenBelegungEintrag MaschinenBelegungEinträge} enthalten.
27: *
28: */
29: public class MitarbeiterKalender extends Kalender {
30:
31: private static final int BEGINN_KERNARBEITSZEIT = 8;
32: private static final int ENDE_KERNARBEITSZEIT = 16;
33:
34: private static final KalenderEintragTyp DEFAULT_TYP = KalenderEintragTyp.ANWESEND;
35: private static final Collection<KalenderEintragTyp> ERLAUBTE_TYPEN = new HashSet<>();
36:
37: static {
38: MitarbeiterKalender.ERLAUBTE_TYPEN.add(KalenderEintragTyp.ANWESEND);
39: MitarbeiterKalender.ERLAUBTE_TYPEN.add(KalenderEintragTyp.ABWESEND);
40: MitarbeiterKalender.ERLAUBTE_TYPEN.add(KalenderEintragTyp.BELEGT);
41: MitarbeiterKalender.ERLAUBTE_TYPEN.add(KalenderEintragTyp.KRANK);
42: }
43:
44: @Override
45: protected void pruefeKalenderEintrag(final KalenderEintrag eintrag) {
46: if (!MitarbeiterKalender.ERLAUBTE_TYPEN.contains(eintrag.getTyp())) {
47: throw new KalenderEintragNichtErlaubtException(String.format("Der Typ %s ist nicht erlaubt für einen Mitarbeiterkalender", eintrag));
48: }
49:
50: if (eintrag.accept(new KalenderEintragVisitor<Boolean>() {
51: @Override
52: public Boolean handle(final MaschinenBelegungEintrag maschinenBelegungEintrag) {
53: return true;
54: }
55:
56: @Override
57: public Boolean handle(final MenschBelegungEintrag menschBelegungEintrag) {
58: return false;
59: }
60:
61: @Override
62: public Boolean handle(final KalenderEintragGenerell kalenderEintragGenerell) {
63: return false;
64: }
65:
66: })) {
67: throw new KalenderEintragNichtErlaubtException("Der übergebene MaschinenBelegungsEintrag kann einem Mitarbeiterkalender nicht hinzugefügt werden!");
68: }
69: }
70:
71: @Override
72: protected Optional<KalenderEintrag> createDefaultEintragZuTag(final LocalDate tag) {
73: return Optional.of(this.createKernarbeitszeitEintrag(tag));
74: }
75:
76: private KalenderEintrag createKernarbeitszeitEintrag(final LocalDate tag) {
77: final LocalDateTime von = tag.atTime(MitarbeiterKalender.BEGINN_KERNARBEITSZEIT, 0);
78: final LocalDateTime bis = tag.atTime(MitarbeiterKalender.ENDE_KERNARBEITSZEIT, 0);
79: return KalenderEintragGenerell.create(von, bis, MitarbeiterKalender.DEFAULT_TYP);
80: }
81:
82: @Override
83: public long getArbeitszeit(final LocalDate tag, final ChronoUnit einheit) {
84: final Collection<Zeitraum> anwesenheitsZeitraeume = this.berechneAnwesenheitsZeitraeume(tag, einheit);
85: final Collection<Zeitraum> anwesenheitenOhneAbwesenheiten = this.vermindereAnwesenheitenUmAbwesenheiten(anwesenheitsZeitraeume, tag);
86: return anwesenheitenOhneAbwesenheiten.stream()
87: .mapToLong(zeitraum -> einheit.between(zeitraum.getVon(), zeitraum.getBis()))
88: .sum();
89: }
90:
91: private Collection<Zeitraum> vermindereAnwesenheitenUmAbwesenheiten(final Collection<Zeitraum> anwesenheitsZeitraeume, final LocalDate tag) {
92: final Collection<Zeitraum> result = new HashSet<>();
93:
94: final Set<Zeitraum> abwesenheiten = this.getEintraegeZuTag(tag).stream()
95: .filter(kalenderEintrag -> kalenderEintrag.getTyp() == KalenderEintragTyp.KRANK)
96: .map(KalenderEintrag::getZeitraum)
97: .collect(Collectors.toSet());
98:
99: anwesenheitsZeitraeume.forEach(anwesenheitsZeitraum -> result.addAll(anwesenheitsZeitraum.entferneZeitraeume(abwesenheiten)));
100:
101: return result;
102: }
103:
104: private Collection<Zeitraum> berechneAnwesenheitsZeitraeume(final LocalDate tag, final ChronoUnit einheit) {
105: final KalenderEintrag kernarbeitszeitEintrag = this.createKernarbeitszeitEintrag(tag);
106: final Collection<Zeitraum> result = CollectionHelper.createSet(kernarbeitszeitEintrag.getZeitraum());
107:
108: final Set<KalenderEintrag> anwesenheiten = this.getEintraegeZuTag(tag).stream()
109: .filter(KalenderEintrag::isVerfuegbar)
110: .collect(Collectors.toSet());
111:
112:• for (final KalenderEintrag anwesenheit : anwesenheiten) {
113: // Wenn die Anwesenheit schon enthalten ist, muss nichts getan werden.
114:• if (!kernarbeitszeitEintrag.contains(anwesenheit)) {
115: // Wenn es nur eine punktuelle Überlappung gibt, kann die Anwesenheit voll angerechnet werden.
116:• if (kernarbeitszeitEintrag.getZeitraum().keineUeberschneidungAusserPunktuell(anwesenheit.getZeitraum())) {
117: result.add(anwesenheit.getZeitraum());
118: } else {
119: // Anwesenheit muss um die Überlappung verkürtzt werden.
120: result.addAll(anwesenheit.getZeitraum().subtract(kernarbeitszeitEintrag.getZeitraum()));
121: }
122: }
123: }
124: return result;
125: }
126:
127: /**
128: * @return alle {@link MenschBelegungEintrag MenschBelegungEinträge},
129: * die in diesem Kalender enthalten sind.
130: */
131: public Set<MenschBelegungEintrag> getBelegungen() {
132: final Set<MenschBelegungEintrag> result = new HashSet<>();
133: for (final Set<KalenderEintrag> eintraege : this.getEintraege().values()) {
134: for (final KalenderEintrag eintrag : eintraege) {
135: eintrag.accept(new KalenderEintragVisitor<Void>() {
136: @Override
137: public Void handle(final MaschinenBelegungEintrag maschinenBelegungEintrag) {
138: // Nothing to do here
139: return null;
140: }
141:
142: @Override
143: public Void handle(final MenschBelegungEintrag menschBelegungEintrag) {
144: result.add(menschBelegungEintrag);
145: return null;
146: }
147:
148: @Override
149: public Void handle(final KalenderEintragGenerell kalenderEintragGenerell) {
150: // Nothing to do here
151: return null;
152: }
153: });
154: }
155: }
156: return result;
157: }
158: }